using System;
using System.Collections.Generic;
using System.Text;
using UMC.Web;


namespace UMC.WorkFlow
{
    [Apiumc("WorkFlow", "Subassembly", Auth = WebAuthType.All, Desc = "设计流程组件")]
    class DesignSubassemblyActivity : UMC.Web.WebActivity
    {
        TaskInstance taskInstance;
        static List<WebMeta> lines = new List<WebMeta>();
        static List<WebMeta> shapes = new List<WebMeta>();
        static List<WebMeta> induceLines = new List<WebMeta>();
        static List<WebMeta> responders = new List<WebMeta>();

        public static void Register<T>() where T : new()
        {
            Type t = typeof(T);

            var mpps = t.GetCustomAttributes(typeof(UIDesignAttribute), false);
            if (mpps.Length > 0)
            {
                var mp = mpps[0] as UIDesignAttribute;
                if (typeof(Line).IsAssignableFrom(t))
                {
                    lines.Add(new WebMeta().Put("type", t.FullName).Put("text", mp.Name).Put("name", t.Name).Put("class", "line"));

                }
                else if (typeof(Shape).IsAssignableFrom(t))
                {
                    shapes.Add(new WebMeta().Put("type", t.FullName).Put("text", mp.Name).Put("name", t.Name).Put("class", "shape"));
                //}
                //else if (typeof(InduceLine).IsAssignableFrom(t))
                //{
                //    //induceLines.Add(new WebMeta().Put("type", t.FullName).Put("text", mp.Name).Put("name", t.Name).Put("class", "induceLine"));

                }
                else if (typeof(Responder).IsAssignableFrom(t))
                {
                    responders.Add(new WebMeta().Put("type", t.FullName).Put("text", mp.Name).Put("name", t.Name).Put("class", "responder"));


                }
            }
            UMC.Data.Reflection.Register<T>(t.Name,t.FullName);

        }


        public static void ScanClass()
        {
            var als = AppDomain.CurrentDomain.GetAssemblies();
            var sb = new StringBuilder();
            foreach (var assembly in als)//mscorlib, 
            {
                var mpp2s = assembly.GetCustomAttributes(typeof(UIDesignAttribute), false);
                if (mpp2s.Length > 0)
                {
                    var types = assembly.GetTypes();
                    foreach (var t in types)
                    {
                        var mpps = t.GetCustomAttributes(typeof(UIDesignAttribute), false);
                        if (mpps.Length > 0)
                        {
                            var mp = mpps[0] as UIDesignAttribute;
                            if (typeof(Line).IsAssignableFrom(t))
                            {
                                //UMC.Data.Reflection.Register()
                                //UMC.Data.Reflection.Register(
                                lines.Add(new WebMeta().Put("type", t.FullName).Put("text", mp.Name).Put("name", t.Name).Put("class", "line"));

                            }
                            else if (typeof(Shape).IsAssignableFrom(t))
                            {
                                shapes.Add(new WebMeta().Put("type", t.FullName).Put("text", mp.Name).Put("name", t.Name).Put("class", "shape"));
                            }
                            else if (typeof(InduceLine).IsAssignableFrom(t))
                            {
                                //induceLines.Add(new WebMeta().Put("type", t.FullName).Put("text", mp.Name).Put("name", t.Name).Put("class", "induceLine"));

                            }
                            else if (typeof(Responder).IsAssignableFrom(t))
                            {
                                responders.Add(new WebMeta().Put("type", t.FullName).Put("text", mp.Name).Put("name", t.Name).Put("class", "responder"));


                            }
                            sb.Append("UMC.WorkFlow.DesignSubassemblyActivity.Register<");
                            sb.Append(t.FullName);
                            sb.AppendLine(">();");

                        }
                    }

                }
            }
            if (sb.Length > 0)
            {

                UMC.Data.Utility.Writer(UMC.Data.Reflection.ConfigPath("Codes/BPM.cs"), sb.ToString());
               
            }
        }

        public override void ProcessActivity(WebRequest request, WebResponse response)
        {
            var Task = UMC.Data.Utility.UInt64Parse(this.AsyncDialog("Task", "none"));
            if (Task.HasValue == false)
            {
                if (lines.Count == 0)
                {
                    ScanClass();
                }
                response.Redirect(new WebMeta().Put("lines", lines).Put("shapes", shapes).Put("induces", induceLines).Put("responders", responders));
            }
            else if (request.IsMaster == false)
            {
                this.Prompt("设计流程需要管理员权限");
            }



            this.taskInstance = UMC.Data.JSON.Deserialize<TaskInstance>(TaskManager.Design(Task.Value));


            var type = UMC.Data.Utility.GetType(this.AsyncDialog("Type", "none"));

            UIDesignAttribute attribute = (UIDesignAttribute)type.GetCustomAttributes(typeof(UIDesignAttribute), false)[0];

            if (typeof(Line).IsAssignableFrom(type))
            {
                var vs = this.AsyncDialog("Line", g =>
                  {
                      var form = new UMC.Web.UIFormDialog() { Title = "添加流程线" };
                      form.AddOption("发起结点", "FromId")
                      .Command(request.Model, "Shape", new WebMeta().Put("Task", Task).Put("Key", "FromId"));
                      form.AddOption("接收结点", "ToId")
                      .Command(request.Model, "Shape", new WebMeta().Put("Task", Task).Put("Key", "ToId"));
                      form.Submit("确认", "WorkFlow.Design");
                      return form;
                  });
                var c = UMC.Data.Reflection.CreateInstance(type) as Line;
                c.FromId = vs["FromId"];
                c.ToId = vs["ToId"];
                c.Text = attribute.Name;
                c.Id = "ine0";// + UMC.Data.Utility.TimeSpan();
                if (c.ToId == c.FromId)
                {
                    this.Prompt("发起结点与接收结点不能相同");
                }
                if (this.taskInstance.Lines.Count > 0)
                {
                    c.Id = String.Format("ine{0}", UMC.Data.Utility.IntParse(this.taskInstance.Lines[this.taskInstance.Lines.Count - 1].Id.Substring(3), 0) + 1);
                }

                var fromInd = this.taskInstance.Lines.Find(g => g.FromId == c.FromId && c.ToId == g.ToId);
                var toInd = this.taskInstance.Lines.Find(g => g.FromId == c.ToId && c.FromId == g.ToId);


                if (fromInd != null || toInd != null)
                {
                    this.Prompt("审批线已经存在");
                }
                else
                {
                    this.taskInstance.Lines.Add(c);
                }
            }
            if (typeof(InduceLine).IsAssignableFrom(type))
            {
                var FromId = this.AsyncDialog("FromId", g =>
                {
                    this.Prompt("参数不正确");
                    return this.DialogValue("none");
                });
                var vs = this.AsyncDialog("InduceLine", g =>
                  {
                      var form = new UMC.Web.UIFormDialog() { Title = "添加驳回线" };
                      form.AddText("按钮标题", "Text", "驳回");
                      form.AddOption("驳回到结点", "ToId", "", "")
                      .Command(request.Model, "Shape", new WebMeta().Put("Task", Task).Put("Key", "ToId"));
                      form.Submit("确认",  "WorkFlow.Design");
                      return form;
                  });
                var c = UMC.Data.Reflection.CreateInstance(type) as InduceLine;
                c.FromId = FromId;// vs["FromId"];
                c.ToId = vs["ToId"];
                c.Text = vs["Text"] ?? attribute.Name;
                c.Id = "ind0";// + UMC.Data.Utility.TimeSpan();

                var ids = new List<String>();
                ids.Add(c.FromId);
                var IsBack = false;
                int count = 100;
                while (ids.Count > 0)
                {
                    var lines = this.taskInstance.Lines.FindAll(fa => ids.Exists(i => i == fa.ToId));
                    if (lines.Exists(li => li.FromId == c.ToId))
                    {
                        IsBack = true;
                        break;
                    }
                    else
                    {
                        ids.Clear();
                        foreach (var l in lines)
                        {
                            ids.Add(l.FromId);
                        }
                    }
                    count--;
                    if (count == 0)
                    {
                        break;
                    }
                }
                if (IsBack == false)
                {
                    this.Prompt("驳回只能到后面的结点");
                }
                if (this.taskInstance.Induces.Count > 0)
                {
                    c.Id = String.Format("ine{0}", UMC.Data.Utility.IntParse(this.taskInstance.Induces[this.taskInstance.Induces.Count - 1].Id.Substring(3), 0) + 1);
                }


                var fromInd = this.taskInstance.Induces.Find(g => g.FromId == c.FromId && c.ToId == g.ToId);
                var toInd = this.taskInstance.Induces.Find(g => g.FromId == c.ToId && c.FromId == g.ToId);


                if (fromInd != null || toInd != null)
                {
                    this.Prompt("驳回线已经存在");
                }
                else
                {
                    this.taskInstance.Induces.Add(c);
                }

            }
            if (typeof(Responder).IsAssignableFrom(type))
            {

                var c = UMC.Data.Reflection.CreateInstance(type) as Responder;
                c.Id = "rsp0";// + UMC.Data.Utility.TimeSpan();
                c.Text = attribute.Name;
                if (this.taskInstance.Registes.Count > 0)
                {
                    c.Id = String.Format("rsp{0}", UMC.Data.Utility.IntParse(this.taskInstance.Registes[this.taskInstance.Registes.Count - 1].Id.Substring(3), 0) + 1);
                }
                this.taskInstance.Registes.Add(c);

            }
            if (typeof(Shape).IsAssignableFrom(type))
            {
                var c = UMC.Data.Reflection.CreateInstance(type) as Shape;
                c.Id = "spe0";// + UMC.Data.Utility.TimeSpan();

                if (this.taskInstance.Shapes.Count > 0)
                {
                    var vs = this.AsyncDialog("Line", g =>
                    {
                        var form = new UMC.Web.UIFormDialog() { Title = "添加审批结点" };
                        form.AddOption("递交人结点", "FromId")
                        .Command(request.Model, "Shape", new WebMeta().Put("Task", Task).Put("Key", "FromId")).NotRequired();
                        form.AddOption("接收人结点", "ToId")
                        .Command(request.Model, "Shape", new WebMeta().Put("Task", Task).Put("Key", "ToId")).NotRequired();
                        form.AddText("结点标题", "Text", attribute.Name);
                        form.Submit("确认", "WorkFlow.Design");
                        return form;
                    });
                    c.Id = String.Format("spe{0}", UMC.Data.Utility.IntParse(this.taskInstance.Shapes[this.taskInstance.Shapes.Count - 1].Id.Substring(3), 0) + 1);
                    var FromId = vs["FromId"];
                    var ToId = vs["ToId"];
                    if (String.IsNullOrEmpty(FromId) && String.IsNullOrEmpty(ToId))
                    {
                        this.Prompt("递交人结点或接收人结点必须有一个");
                    }
                    if (ToId == "spe0")
                    {
                        this.Prompt("接收人结点不能是开始结点");
                    }
                    if (FromId == ToId)
                    {
                        this.Prompt("递交人结点与接收人结点不能相同");
                    }

                    if (String.IsNullOrEmpty(FromId) == false)
                    {
                        var line = new Subassembly.Line();
                        line.FromId = FromId;
                        line.ToId = c.Id;
                        line.Text = "方向线";
                        line.Id = "ind0";// + UMC.Data.Utility.TimeSpan();


                        if (this.taskInstance.Lines.Count > 0)
                        {
                            line.Id = String.Format("ine{0}", UMC.Data.Utility.IntParse(this.taskInstance.Lines[this.taskInstance.Lines.Count - 1].Id.Substring(3), 0) + 1);
                        }
                        this.taskInstance.Lines.Add(line);

                    }
                    if (String.IsNullOrEmpty(ToId) == false)
                    {
                        var line = new Subassembly.Line();
                        line.FromId = c.Id;
                        line.ToId = ToId;
                        line.Text = "方向线";
                        line.Id = "ind0";// + UMC.Data.Utility.TimeSpan();


                        if (this.taskInstance.Lines.Count > 0)
                        {
                            line.Id = String.Format("ine{0}", UMC.Data.Utility.IntParse(this.taskInstance.Lines[this.taskInstance.Lines.Count - 1].Id.Substring(3), 0) + 1);
                        }
                        this.taskInstance.Lines.Add(line);

                    }


                    c.Text = vs["Text"] ?? attribute.Name;
                    this.taskInstance.Shapes.Add(c);
                }
                else
                {
                    c.Text = attribute.Name;
                    this.taskInstance.Shapes.Add(c);
                }

            }

            TaskManager.Design(this.taskInstance, this.Context.Token.Username);
            this.Context.Send("WorkFlow.Design", new WebMeta().Put("Task", this.taskInstance), true);


        }

    }
}